home *** CD-ROM | disk | FTP | other *** search
- ; SIMLIFY.S
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Scheme code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Program Simplification *
- ;* (for use only after alpha conversion) *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: David Bartley Date: Oct 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
-
- (define pcs-simplify
- (lambda (exp)
- (letrec
- ;-------!
- ((simp
- (lambda (x)
- (if (atom? x)
- x
- (case (car x)
- (quote x)
- (#!TOKEN x) ; ID record
- (lambda (simp-lambda x))
- (if (simp-if (simp (if-pred x))
- (simp (if-then x))
- (simp (if-else x))))
- (set! (simp-set! (set!-id x)
- (simp (set!-exp x))))
- (begin (simp-begin (simp-args (cdr x) '())))
- (letrec (simp-letrec
- (simp-pairs (letrec-pairs x) '())
- (simp (letrec-body x))))
- (else (simp-application (simp-args x '())))
- ))))
-
- (simp-lambda
- (lambda (x) ; note: preserve extra slots in the node
- (begin ; This changes the apparent output of PME!!
- (set-lambda-body x (simp (lambda-body x)))
- x)))
-
- (simp-if
- (lambda (p th el)
- (cond ;; --- (if p (if p a b) c) ==> (if p a c)
-
- ((and (eq? (car th) 'if)
- (dupe? p) ; no side effects
- (equal? p (if-pred th)))
- (simp-if p (if-then th) el))
-
- ;; --- (if p a (if p b c)) ==> (if p a c)
-
- ((and (eq? (car el) 'if)
- (dupe? p) ; no side effects
- (equal? p (if-pred el)))
- (simp-if p th (if-else el)))
-
- ;; --- (if #F a b) ==> b
- ;; --- (if '* a b) ==> a
-
- ((eq? (car p) 'quote)
- (if (cadr p) th el))
-
- ;; --- (if (not a) b c) ==> (if a c b)
-
- ((eq? (car p) 'not)
- (simp-if (cadr p) el th))
-
- ;; --- (if (begin ... p) a b)
- ;; ==> (begin ... (if p a b))
-
- ((eq? (car p) 'begin)
- (let ((sl (reverse (cdr p))))
- (simp-begin
- (%reverse! (cons (simp-if (car sl) th el)
- (cdr sl))))))
-
- ;; --- (if (if a b c) d e)
- ;;
- ;; ==> (if a (if b d e)
- ;; (if c d e))
-
- ((eq? (car p) 'if)
- (cond ((dupe? th)
- (let ((a (if-pred p))
- (b (if-then p))
- (c (if-else p)))
- (cond
- ;; --- (if (if a 't c) d e)
- ;; ==> (if a d (if c d e))
-
- ((and (pair? b)
- (eq? (car b) 'QUOTE)
- (cadr b))
- (simp-if a th
- (simp-if c th el)))
-
- ;; --- (if (if a b 't) d e)
- ;; ==> (if a (if b d e) d)
-
- ((and (pair? c)
- (eq? (car c) 'QUOTE)
- (cadr c))
- (simp-if a (simp-if b th el) th))
-
- ;; --- (if (if a a c) d e)
- ;; ==> (if a d (if c d e))
-
- ((and (dupe? a)(equal? a b))
- (simp-if a th (simp-if c th el)))
-
- (else
- (list 'if p th el)))))
-
- ;; The following turns out to "pessimize" the code
- ;; given the current code generator algorithms
-
- ;; ((dupe? el)
- ;; (let ((a (if-pred p))
- ;; (b (if-then p))
- ;; (c (if-else p)))
- ;; (cond
- ;; --- (if (if a #F c) d e)
- ;; ==> (if a e (if c d e))
-
- ;; ((equal? b '(quote #F))
- ;; (simp-if a el (simp-if c th el)))
-
- ;; --- (if (if a b #F) d e)
- ;; ==> (if a (if b d e) e)
-
- ;; ((equal? c '(quote #F))
- ;; (simp-if a (simp-if b th el) el))
- ;; (else
- ;; (list 'if p th el)))))
-
- (else
- (list 'if p th el))))
-
- (else
- (list 'if p th el)))))
-
- (dupe?
- (lambda (x)
- (or (atom? x)
- (memq (car x) '(#!TOKEN QUOTE %%get-global%% %%get-fluid%%)))))
-
- (simp-set!
- (lambda (id exp)
- (cond
- ;; --- (set! a a) ==> a
-
- ((eq? id exp) id)
-
- ;; --- (set! x (if a b c))
- ;; ==> (if a (set! x b)(set! x c))
-
- ((eq? (car exp) 'if)
- (simp-if (if-pred exp)
- (simp-set! id (if-then exp))
- (simp-set! id (if-else exp))))
- (else
- (list 'set! id exp)))))
-
- (simp-begin
- (lambda (sl)
- (let ((sl (s-begin (%reverse! sl) '())))
- (cond ((null? sl) '(quote ()))
- ((null? (cdr sl)) (car sl))
- (else
- (cons 'begin sl))))))
-
- (s-begin
- (lambda (old new)
- (if (null? old)
- new
- (let ((s (car old)))
- (cond ((and new ; not last exp
- (memq (car s) '(#!TOKEN QUOTE LAMBDA %%get-global%% %%get-fluid%%)))
- (s-begin (cdr old) new)) ; delete s
- ((or (eq? (car s) 'begin)
- (and new (no-se-op (car s))))
- (s-begin (append! (%reverse! (cdr s))
- (cdr old))
- new))
- (else (s-begin (cdr old)
- (cons s new))))))))
-
- ; (simp-apply
- ; (lambda (fun arg)
- ; (cond
- ; ;; --- (apply (lambda (a ...) body) arg)
- ; ;; ==> (let ((L arg))
- ; ;; (let ((a (car L))...) body))
- ;
- ; ((and (eq? (car fun) 'lambda)
- ; (not (negative? (lambda-nargs fun))))
- ; (simp-apply-letrec
- ; (lambda-bvl fun) (lambda-body fun) arg #F))
- ;
- ; (else (list '%apply fun arg)))))
-
- ;(simp-apply-letrec
- ;(lambda (bvl body arg dupe?)
- ; ;; (apply (lambda () body) L)
- ; ;; ==> (begin L body)
- ; (if (null? bvl)
- ; (simp-begin (list arg body))
- ; (let ((a (car bvl)))
- ; (cond
- ; ;; (apply (lambda (a ...) body) (cons x y))
- ; ;; ==> (let ((a x))
- ; ;; (apply (lambda (...) body) y))
- ; ((eq? (car arg) 'cons)
- ; (simp-letrec
- ; `((,a ,(cadr arg)))
- ; (simp-apply-letrec
- ; (cdr bvl) body (caddr arg) #F)))
- ;
- ; ;; (apply (lambda (a) body) L)
- ; ;; ==> (let ((a (car L))) body)
- ; ((null? (cdr bvl))
- ; (simp-letrec
- ; `((,a (car ,arg)))
- ; body))
- ; ;; (apply (lambda (a...) body) triv)
- ; ;; ==> (let ((a (car triv)))
- ; ;; (apply (lambda (...) body)
- ; ;; (cdr triv)))
- ; ((or dupe?
- ; (memq (car arg) '(#!TOKEN QUOTE)))
- ; (simp-letrec
- ; `((,a (car ,arg)))
- ; (simp-apply-letrec
- ; (cdr bvl) body `(cdr ,arg) 't)))
- ;
- ; ;; (apply (lambda (a...) body) L)
- ; ;; ==> (let ((temp L))
- ; ;; (let ((a (car L)))
- ; ;; (apply (lambda (...) body)
- ; ;; (cdr temp))))
- ; (else
- ; (let ((temp (pcs-make-id '())))
- ; (simp-letrec
- ; `((,temp ,arg))
- ; (simp-letrec
- ; `((,a (car ,temp)))
- ; (simp-apply-letrec
- ; (cdr bvl) body `(cdr ,temp) 't)))))
- ; )))))
-
- (simp-letrec
- (lambda (pairs body)
- (cond
- ;; --- (letrec () body) ==> body
-
- ((and (null? pairs)
- (not debug-mode))
- body)
-
- ;; --- (letrec ((a '*)...)
- ;; (begin (set! a value) ...))
- ;; --- (letrec (...(a value))
- ;; (begin ...))
-
- ; omit: works, but not worth doing
- ; ((and (eq? (car body) 'begin)
- ; (eq? (car (cadr body)) 'set!)
- ; (eq? (set!-id (cadr body)) (caar pairs))
- ; (eq? (car (cadar pairs)) 'quote)
- ; (memq (car (set!-exp (cadr body)))
- ; '(quote lambda)))
- ; (simp-letrec
- ; (append (cdr pairs)
- ; (list
- ; (list (caar pairs)
- ; (set!-exp (cadr body)))))
- ; (simp-begin
- ; (cddr body))))
-
- ;; --- (letrec ((a '*)...)
- ;; (set! a value))
- ;; --- (letrec (...(a value))
- ;; a)
-
- ; omit: works, but not worth doing
- ; ((and (eq? (car body) 'set!)
- ; (eq? (set!-id body) (caar pairs))
- ; (eq? (car (cadar pairs)) 'quote)
- ; (memq (car (set!-exp body))
- ; '(quote lambda)))
- ; (simp-letrec
- ; (append! (cdr pairs)
- ; (list
- ; (list (set!-id body)
- ; (set!-exp body))))
- ; (set!-id body)))
-
- (else (list 'letrec pairs body)))))
-
- (simp-pairs
- (lambda (old new)
- (if (null? old)
- (%reverse! new)
- (simp-pairs (cdr old)
- (cons (list (caar old)
- (simp (cadar old)))
- new)))))
-
- (simp-car
- (lambda (x)
- (if (atom? x)
- (list 'CAR x)
- (let ((op (assq (car x) '((CAR . CAAR)(CADR . CAADR)
- (CDR . CADR)(CDDR . CADDR)
- (CDDDR . CADDDR)))))
- (if op
- (cons (cdr op)(cdr x))
- (list 'CAR x))))))
-
- (simp-cdr
- (lambda (x)
- (if (atom? x)
- (list 'CDR x)
- (let ((op (assq (car x) '((CAR . CDAR)(CADR . CDADR)
- (CDR . CDDR)(CDDR . CDDDR)))))
- (if op
- (cons (cdr op)(cdr x))
- (list 'CDR x))))))
-
- (simp-=
- (lambda (op x y)
- (if (and (eq? (car y) 'QUOTE)
- (number? (cadr y)))
- (let ((rop (assq op '((= . =) (< . >) (> . <)
- (<= . >=) (>= . <=) (<> . <>)))))
- (if rop
- (list (cdr rop) y x)
- (list op x y)))
- (list op x y))))
-
- (simp-application
- (lambda (comb) ; COMB is already simplified
- (let ((f (car comb))
- (args (cdr comb)))
- (cond ((atom? f) ; primitive
- (case f
- ; ((%apply) (simp-apply (car args) (cadr args)))
- ((car) (simp-car (car args)))
- ((cdr) (simp-cdr (car args)))
- ((= < > <= >= <>)
- (simp-= f (car args) (cadr args)))
- (else
- comb)))
-
- ;; --- ((lambda () body)) ==> body
-
- ((and (not debug-mode)
- (eq? (car f) 'lambda)
- (null? args)
- (null? (lambda-bvl f)))
- (lambda-body f))
-
- ;; --- ((lambda (a b)(foo a b))
- ;; x y)
- ;; ==> (foo x y)
-
- ((and (not debug-mode)
- (eq? (car f) 'lambda)
- (let ((foo (car (lambda-body f))))
- (cond ((atom? foo)
- (getprop foo 'pcs*opcode))
- ((eq? (car foo) '#!TOKEN)
- (not (memq foo (lambda-bvl f))))
- (else
- (eq? (car foo) '%%get-global%%))))
- (equal? (cdr (lambda-body f)) ; (... a b)
- (lambda-bvl f))) ; (a b)
- (simp-application
- (cons (car (lambda-body f))
- args)))
-
- ;; --- ((letrec pairs body) . args)
- ;; ==> (letrec pairs (body . args))
-
- ((eq? (car f) 'letrec)
- (simp-letrec
- (letrec-pairs f)
- (simp-application
- `(,(letrec-body f) . ,args))))
-
- (else comb)))))
-
- (simp-args
- (lambda (old new)
- (if (null? old)
- (%reverse! new)
- (simp-args (cdr old)
- (cons (simp (car old))
- new)))))
-
- (no-se-op
- (lambda (op)
- (and (symbol? op)
- (getprop op 'pcs*primop-handler) ; not a 'magic' primop
- (let ((opcode (getprop op 'pcs*opcode)))
- (and (integer? opcode)
- (positive? opcode))))))
-
- ; data
-
- (debug-mode pcs-debug-mode)
-
- ;-------!
- )
- (simp exp))))